using System;
using System.Collections;
using System.Data;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Web;
using Dimok.Credit.DSs;
using Dimok.Data;
using Dimok.Data.Database;


////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Dimok.Credit
//
// summary:	.
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Dimok.Credit {
	public class NMR {

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a credit information. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="SSN">				The ssn. </param>
		/// <param name="firstName">	Name of the first. </param>
		/// <param name="lastName">		Name of the last. </param>
		/// <param name="city">				The city. </param>
		/// <param name="state">			The state. </param>
		/// <param name="SSN1">				The first ssn. </param>
		/// <param name="firstName1">	The first first name. </param>
		/// <param name="lastName1">	The first last name. </param>
		/// <param name="city1">			The first city. </param>
		/// <param name="state1">			The first state. </param>
		///
		/// <returns>	The credit information. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Trades GetCreditInfo(object SSN,object firstName,object lastName,object city,object state,object SSN1,object firstName1,object lastName1,object city1,object state1){
			return GetCreditInfo(SSN.ToString(),firstName.ToString(),lastName.ToString(),city.ToString(),state.ToString(),SSN1.ToString(),firstName1.ToString(),lastName1.ToString(),city1.ToString(),state1);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a credit information. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="connection">		The connection. </param>
		/// <param name="borrowerID">		Identifier for the borrower. </param>
		/// <param name="SSN">					The ssn. </param>
		/// <param name="firstName">		Name of the first. </param>
		/// <param name="lastName">			Name of the last. </param>
		/// <param name="city">					The city. </param>
		/// <param name="state">				The state. </param>
		/// <param name="coBorrowerID">	Identifier for the co borrower. </param>
		/// <param name="SSN1">					The first ssn. </param>
		/// <param name="firstName1">		The first first name. </param>
		/// <param name="lastName1">		The first last name. </param>
		/// <param name="city1">				The first city. </param>
		/// <param name="state1">				The first state. </param>
		///
		/// <returns>	The credit information. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Trades GetCreditInfo(string connection,int borrowerID,string SSN,string firstName,string lastName,string city,string state,int coBorrowerID,string SSN1,string firstName1,string lastName1,string city1,string state1){
			string response = Pull(BuildRequest(connection,borrowerID,SSN,firstName,lastName,city,state,coBorrowerID,SSN1,firstName1,lastName1,city1,state1));
			return ParseCredit(response);
			//if( SSN1 != "" )FileManager.GetFileFromBytes(response,@"C:\Data\Dimok\Docs\AMFC\Banker\NMRMISMOINterface\Response1.xml",true);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Parse credit. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="xmlReport">	The xml report. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Trades ParseCredit(string xmlReport){
			MISMO_RESPONSE_DS dsResp = new Dimok.Credit.DSs.MISMO_RESPONSE_DS();
			MISMO_RESPONSE_P_DS dsPublic = new Dimok.Credit.DSs.MISMO_RESPONSE_P_DS();
			LoadCustomDataSet(dsResp,xmlReport);
			LoadCustomDataSet(dsPublic,xmlReport);
			CheckError(dsResp);
			Trades dsTrades = new Trades();
			int borrowerID = int.Parse(dsResp.BORROWER[0].BorrowerID);
			int coBorrowerID = dsResp.BORROWER.Count > 1 ? int.Parse(dsResp.BORROWER[1].BorrowerID) : 0;
			#region CREDIT_LIABILITY
			dsResp.CREDIT_LIABILITY.BorrowerIDColumn.ReadOnly = true;
			foreach( MISMO_RESPONSE_DS.CREDIT_LIABILITYRow drTrade in dsResp.CREDIT_LIABILITY ){
				MISMO_RESPONSE_DS._CURRENT_RATINGRow[] curRatingRows = dsResp.CREDIT_LIABILITY[1].Get_CURRENT_RATINGRows();
				Trades.t_CreditLiabilityRow creditLiabRow = dsTrades.t_CreditLiability.Newt_CreditLiabilityRow();
				creditLiabRow.BorrowerID = borrowerID;
				SQLHelperEx.UpdateDataRow(creditLiabRow,drTrade);
				creditLiabRow._CURRENT_RATING_Code = (byte)drTrade.Get_CURRENT_RATINGRows()[0]._Code;
				SQLHelperEx.UpdateDataRow(creditLiabRow,drTrade.Get_LATE_COUNTRows()[0]);
				SQLHelperEx.UpdateDataRow(creditLiabRow,drTrade.Get_PAYMENT_PATTERNRows()[0]);
				creditLiabRow.CREDIT_COMMENT = drTrade.GetCREDIT_COMMENTRows()[0]._Text;
				SetApplicantIDs(borrowerID,drTrade,creditLiabRow);
				/*
				int applID = GetBorrowerID(drTrade.BorrowerID);
				if( applID == borrowerID ){
					creditLiabRow.ApplicantID = applID;
					if( (applID = GetCoBorrowerID(drTrade.BorrowerID)) > 0 )
						creditLiabRow.CoApplicantID = applID;
				}else creditLiabRow.CoApplicantID = applID;
				*/
				dsTrades.t_CreditLiability.Addt_CreditLiabilityRow(creditLiabRow);
			}
			#endregion CREDIT_LIABILITY
			#region CREDIT_PUBLIC_RECORD
			dsPublic.CREDIT_PUBLIC_RECORD.BorrowerIDColumn.ReadOnly = true;
			foreach( MISMO_RESPONSE_P_DS.CREDIT_PUBLIC_RECORDRow pubRecRow in dsPublic.CREDIT_PUBLIC_RECORD ){
				Trades.t_PublicRecordRow rowPubRec = dsTrades.t_PublicRecord.Newt_PublicRecordRow();
				rowPubRec.BorrowerID = borrowerID;
				SQLHelperEx.UpdateDataRow(rowPubRec,pubRecRow);
				SQLHelperEx.UpdateDataRow(rowPubRec,pubRecRow.GetCREDIT_COMMENTRows()[0]);
				SetApplicantIDs(borrowerID,pubRecRow,rowPubRec);
				dsTrades.t_PublicRecord.Addt_PublicRecordRow(rowPubRec);
			}
			#endregion CREDIT_PUBLIC_RECORD
			#region CreditInfo
			Trades.t_CreditInfo_MortgageRow creditInfoRow = dsTrades.t_CreditInfo_Mortgage.Newt_CreditInfo_MortgageRow();
			creditInfoRow.ReportXML = xmlReport;
			creditInfoRow.ReportMerged = dsResp.EMBEDDED_FILE[0].DOCUMENT;
			SetScores(dsResp,creditInfoRow,borrowerID);
			DateTimeFormatInfo dtInfo = new DateTimeFormatInfo();
			dtInfo.FullDateTimePattern = "yyyy'-'M'-'d'T'H':'m':'s";
			creditInfoRow.DatePulled = DateTime.Parse( dsResp.RESPONSE[0].ResponseDateTime,dtInfo);
			dsTrades.t_CreditInfo_Mortgage.Addt_CreditInfo_MortgageRow(creditInfoRow);
			if( coBorrowerID > 0 ){
				creditInfoRow = dsTrades.t_CreditInfo_Mortgage.Newt_CreditInfo_MortgageRow();
				SetScores(dsResp,creditInfoRow,coBorrowerID);
				dsTrades.t_CreditInfo_Mortgage.Addt_CreditInfo_MortgageRow(creditInfoRow);
			}
			#endregion CreditInfo
			return dsTrades;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Sets an applicant i ds. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="borrowerID">	Identifier for the borrower. </param>
		/// <param name="drTrade">		The dr trade. </param>
		/// <param name="dataRow">		The data row. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static void SetApplicantIDs(int borrowerID,DataRow drTrade,DataRow dataRow){
			string borrower = drTrade["BorrowerID"].ToString();
			int applID = GetBorrowerID(borrower);
			if( applID == borrowerID ){
				dataRow["BorrowerID"] = applID;
				if( (applID = GetCoBorrowerID(borrower)) > 0 )
					dataRow["CoBorrowerID"] = applID;
			}else dataRow["CoBorrowerID"] = applID;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Sets the scores. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="dsResponse">			The ds response. </param>
		/// <param name="creditInfoRow">	The credit information row. </param>
		/// <param name="borrowerID">			Identifier for the borrower. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static void SetScores(MISMO_RESPONSE_DS dsResponse,Trades.t_CreditInfo_MortgageRow creditInfoRow,int borrowerID){
			short score = GetScore(dsResponse,borrowerID,"Equifax");
			if( score > 0 )creditInfoRow.ScoreEfx = score;
			score = GetScore(dsResponse,borrowerID,"Experian");
			if( score > 0 )creditInfoRow.ScoreXpn = score;
			score = GetScore(dsResponse,borrowerID,"TransUnion");
			if( score > 0 )creditInfoRow.ScoreTU = score;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a score. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="dsResponse">									The ds response. </param>
		/// <param name="borrowerID">									Identifier for the borrower. </param>
		/// <param name="CreditRepositorySourceType">	Type of the credit repository source. </param>
		///
		/// <returns>	The score. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static short GetScore(MISMO_RESPONSE_DS dsResponse,int borrowerID,string CreditRepositorySourceType){
			MISMO_RESPONSE_DS.CREDIT_SCORERow[] scoreRows = (MISMO_RESPONSE_DS.CREDIT_SCORERow[])dsResponse.CREDIT_SCORE.Select("BorrowerID='"+borrowerID+"' AND CreditRepositorySourceType='"+CreditRepositorySourceType+"' AND _Value > ''");
			return scoreRows.Length > 0 ? short.Parse(scoreRows[0]._Value) : (short)0;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a borrower identifier. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="borrowerID">	Identifier for the borrower. </param>
		///
		/// <returns>	The borrower identifier. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static int GetBorrowerID(string borrowerID){return int.Parse(Regex.Replace(borrowerID,@"\s+\d+$",""));}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a co borrower identifier. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="borrowerID">	Identifier for the borrower. </param>
		///
		/// <returns>	The co borrower identifier. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static int GetCoBorrowerID(string borrowerID){
			string id = Regex.Match(borrowerID,@"\s+\d+$").Value.Trim();
			return id == "" ? 0 : int.Parse(id);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Loads a custom data set. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="dsCustom">	The ds custom. </param>
		/// <param name="xml">			The xml. </param>
		///
		/// <returns>	The custom data set. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static XmlDataDocument LoadCustomDataSet(DataSet dsCustom,string xml){
			XmlDataDocument xmlDS = new XmlDataDocument(dsCustom);
			xmlDS.LoadXml(xml);
			return xmlDS;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Check error. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <exception cref="CreditReportException">	Thrown when creditreport. </exception>
		///
		/// <param name="dsResponse">	The ds response. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static void CheckError(MISMO_RESPONSE_DS dsResponse){
			if( dsResponse.CREDIT_RESPONSE[0].CreditReportType != "Error" )return;
			ArrayList alCols = new ArrayList();
			foreach( MISMO_RESPONSE_DS.CREDIT_ERROR_MESSAGERow creditErrorRow in dsResponse.CREDIT_RESPONSE[0].GetCREDIT_ERROR_MESSAGERows() )
				foreach( DataColumn colError in creditErrorRow.Table.Columns )
					alCols.Add(colError.ColumnName+":"+creditErrorRow[colError]);
			throw new CreditReportException(string.Join(Environment.NewLine,(string[])alCols.ToArray(typeof(string))));
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Pulls the given xmlRequest. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="xmlRequest">	The xml request. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string Pull(string xmlRequest){
			WebClient wc = new WebClient();
			byte[] response = wc.UploadData(Config.Credit.NMR.URL,Encoding.ASCII.GetBytes(xmlRequest));
			return XmlEx.GetOuterXML(Encoding.ASCII.GetString(response));
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Builds a request. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="connection">	The connection. </param>
		/// <param name="SSN">				The ssn. </param>
		/// <param name="firstName">	Name of the first. </param>
		/// <param name="lastName">		Name of the last. </param>
		/// <param name="city">				The city. </param>
		/// <param name="state">			The state. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string BuildRequest(string connection,string SSN,string firstName,string lastName,string city,string state){
			return BuildRequest(connection,0,SSN,firstName,lastName,city,state,0,"","","","","");
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Builds a request. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <exception cref="Exception">	Thrown when exception. </exception>
		///
		/// <param name="conn">					The connection. </param>
		/// <param name="borrowerID">		Identifier for the borrower. </param>
		/// <param name="SSN">					The ssn. </param>
		/// <param name="firstName">		Name of the first. </param>
		/// <param name="lastName">			Name of the last. </param>
		/// <param name="city">					The city. </param>
		/// <param name="state">				The state. </param>
		/// <param name="coBorrowerID">	Identifier for the co borrower. </param>
		/// <param name="SSN1">					The first ssn. </param>
		/// <param name="firstName1">		The first first name. </param>
		/// <param name="lastName1">		The first last name. </param>
		/// <param name="city1">				The first city. </param>
		/// <param name="state1">				The first state. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string BuildRequest(string conn,int borrowerID,string SSN,string firstName,string lastName,string city,string state,int coBorrowerID,string SSN1,string firstName1,string lastName1,string city1,string state1){
			const string LenderCaseIdentifier = "11232145";
			MISMO_DS dsMismo = new MISMO_DS();
			ApplForCredit.t_NameSpace_XpertOnlineRow rowCred = XpertOnLine.XpertOnline(conn);
			if( rowCred == null )throw new Exception("Company is not set up to pull credit.\nGo to XpertOnline.");
			#region REQUEST_GROUP
			dsMismo.REQUEST_GROUP.AddREQUEST_GROUPRow(rowCred.MISMOVersionID);
			MISMO_DS.REQUEST_GROUPRow regGroupRow = dsMismo.REQUEST_GROUP[0];
			dsMismo.RECEIVING_PARTY.AddRECEIVING_PARTYRow(rowCred.ProviderID,regGroupRow);
			dsMismo.SUBMITTING_PARTY.AddSUBMITTING_PARTYRow(rowCred.CompanyName,regGroupRow);
			dsMismo.REQUEST.AddREQUESTRow(DateTime.Now.ToString("s"),rowCred.CompanyID,rowCred.UserName,rowCred.Password,regGroupRow);
				#region CREDIT_REQUEST_DATA
			dsMismo.REQUEST_DATA.AddREQUEST_DATARow(dsMismo.REQUEST[0]);
			dsMismo.CREDIT_REQUEST.AddCREDIT_REQUESTRow(rowCred.MISMOVersionID,LenderCaseIdentifier,"SYSTEM",dsMismo.REQUEST_DATA[0]);
			dsMismo.CREDIT_REQUEST_DATA.AddCREDIT_REQUEST_DATARow("1",borrowerID+"","","Submit","Merge",DateTime.Now.ToString("s"),GetCreditRequestType(coBorrowerID),dsMismo.CREDIT_REQUEST[0]);
			MISMO_DS.CREDIT_REQUEST_DATARow creditReqDataRow = dsMismo.CREDIT_REQUEST_DATA[0];
			dsMismo.CREDIT_REPOSITORY_INCLUDED.AddCREDIT_REPOSITORY_INCLUDEDRow("Y","Y","Y",creditReqDataRow);
			dsMismo.CREDIT_SCORE_MODEL_NAME.AddCREDIT_SCORE_MODEL_NAMERow("EquifaxBeacon",creditReqDataRow);
			dsMismo.CREDIT_SCORE_MODEL_NAME.AddCREDIT_SCORE_MODEL_NAMERow("ExperianFairIsaac",creditReqDataRow);
			dsMismo.CREDIT_SCORE_MODEL_NAME.AddCREDIT_SCORE_MODEL_NAMERow("TransUnionEmpirica",creditReqDataRow);
				#endregion CREDIT_REQUEST_DATA
				#region LOAN_APPLICATION
			dsMismo.LOAN_APPLICATION.AddLOAN_APPLICATIONRow(dsMismo.CREDIT_REQUEST[0]);
			MISMO_DS.LOAN_APPLICATIONRow loanApplRow = dsMismo.LOAN_APPLICATION[0];
			dsMismo.BORROWER.AddBORROWERRow(borrowerID+"",firstName,"",lastName,"","","Borrower",SSN,loanApplRow);
			dsMismo._RESIDENCE.Add_RESIDENCERow("15687 PALM DRIVE #128","Miami","FL","33180","Current",dsMismo.BORROWER[0]);
			if( coBorrowerID > 0 ){
				dsMismo.BORROWER.AddBORROWERRow(coBorrowerID+"",firstName1,"",lastName1,"","","CoBorrower",SSN1,loanApplRow);
				dsMismo._RESIDENCE.Add_RESIDENCERow("15687 PALM DRIVE #128","Miami","FL","33180","Current",dsMismo.BORROWER[1]);
			}
				#endregion LOAN_APPLICATION
			#endregion
			//if( SSN1 != "" )FileManager.GetFileFromBytes("",@"C:\Data\Dimok\Docs\AMFC\Banker\NMRMISMOINterface\Request1.xml",true);
			return XmlEx.GetInnerXML(dsMismo.GetXml());
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a credit request type. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="coBorrowerID">	Identifier for the co borrower. </param>
		///
		/// <returns>	The credit request type. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static string GetCreditRequestType(int coBorrowerID){return coBorrowerID>0?"Individual":"Joint";}
	}
}
